home *** CD-ROM | disk | FTP | other *** search
Text File | 1994-12-08 | 48.0 KB | 1,557 lines | [TEXT/R*ch] |
- C.S.M.P. Digest Wed, 10 Feb 93 Volume 2 : Issue 11
-
- Today's Topics:
-
- Help for a new programmer (CDEF's & Debuging Resource Code)
- Proper way to do Self-Modifying code?
- help- sound playing w/ bufferCmd
- code for Finding Prefs File (long)
-
-
-
- The Comp.Sys.Mac.Programmer Digest is moderated by Michael A. Kelly.
-
- The digest is a collection of article threads from the internet newsgroup
- comp.sys.mac.programmer. It is designed for people who read c.s.m.p. semi-
- regularly and want an archive of the discussions. If you don't know what a
- newsgroup is, you probably don't have access to it. Ask your systems
- administrator(s) for details. If you don't have access to news, you can
- post articles to any newsgroup by mailing your article to
- newsgroup@cs.utexas.edu
- So, to post an article to comp.sys.mac.programmer, mail your article to
- comp-sys-mac-programmer@cs.utexas.edu
- Note the '-' instead of '.' in the newsgroup name. Be sure to ask that
- replies be emailed to you instead of posted to the group, and give your
- email address.
-
- Each issue of the digest contains one or more sets of articles (called
- threads), with each set corresponding to a 'discussion' of a particular
- subject. The articles are not edited; all articles included in this digest
- are in their original posted form (as received by our news server at
- cs.uoregon.edu). Article threads are not added to the digest until the last
- article added to the thread is at least one month old (this is to ensure that
- the thread is dead before adding it to the digest). Article threads that
- consist of only one message are generally not included in the digest.
-
- The entire digest is available for anonymous ftp from ftp.cs.uoregon.edu
- [128.223.8.8] in the directory /pub/mac/csmp-digest. Be sure to read the
- file /pub/mac/csmp-digest/README before downloading any files. The most
- recent issues are available from sumex-aim.stanford.edu [36.44.0.6] in the
- directory /info-mac/digest/csmp. If you don't have ftp capability, the sumex
- archive has a mail server; send a message with the text '$MACarch help' (no
- quotes) to LISTSERV@ricevm1.rice.edu for more information.
-
- The digest is also available via email. Just send a note saying that you
- want to be on the digest mailing list to mkelly@cs.uoregon.edu, and you will
- automatically receive each new issue as it is created. Sorry, back issues
- are not available through the mailing list.
-
- Send administrative mail to mkelly@cs.uoregon.edu.
-
-
- -------------------------------------------------------
-
- From: kevinb@engr.LaTech.edu (Kevin P. Brunner)
- Subject: Help for a new programmer (CDEF's & Debuging Resource Code)
- Date: 6 Jan 93 04:55:39 GMT
- Organization: Louisiana Tech University
-
-
- I've been working on the mac for the last 6 months, recently converted from
- ibm p.c. I'm getting my feet wet with controls and resources. I have been
- able to create small apps with standard mac stuff, but would like to design
- my own controls. Inside Macintosh does a lot for stating generalities...
- "you need this, and one of these, and, oh!, one of these too..." but no
- specific examples in this case.
-
- So I've tried creating a CDEF which responds only to the draw message and
- returns zero (0) for everything else. It responds, but draws something
- completely different than what the code says. The code inverts a block
- of pixels in a window (it works when called from the "main" block of code,
- but not when the resource is compiled seperately -- I get a rounded box!)
-
- Has anyone written custom controls? If so, do you mind sharing a portion
- of your code and development technique? Also, any help on using Think C
- to debug resources would be appreciated. I have most of the Inside Mac's and
- both Programming the Macintosh's (vol 1 and 2) I have looked elsewhere but
- have found nothing with coding examples or techniques. Book or Article
- references would be appreciated as well.
-
- Thanks in advance!
-
- kevinb@engr.latech.edu
-
- +++++++++++++++++++++++++++
-
- Organization: Royal Institute of Technology, Stockholm, Sweden
- Date: Wed, 6 Jan 1993 14:56:05 GMT
-
- > How to debug CDEF in Think C
-
- Well, you could try and create a CDEF that's only 6 bytes,
- load it in, make it contain a JMP instruction and the
- address of a function in your application, and flush the
- cache (after locking the resource)
-
- Something like:
-
- typedef struct cdef {
-
- unsigned short jmp ;
- short * ( addr ) ( ) ;
-
- } cdefStub ;
-
-
- pascal short
- MyRealCDEF ( whatever )
- {
- Do the stuff
- }
-
-
- /* DO this before creating any controls */
-
- cdefStub stub ;
- Handle h = GetReosurce ( 'CDEF' , 4711 ) ;
-
- stub . jmp = 0x4000 ; /* Have to look this up, JMP Immediate */
- stub . addr = MyRealCDEF ;
-
- HLockHi ( h ) ; /* Top of heap to avoid fragmentation */
-
- * ( cdefStub * ) * h = stub ;
-
- if ( TrapAvailable ( _HWTrap ) ) {
-
-
- FlushInstructionCache ( ) ;
- }
-
-
- Now anything going to CDEF 4711 in your program will go to
- the function MyRealCDEF, and you can use the source debugger
- on it, and reference globals even! Cool!
-
-
- - --
- -- Jon W{tte, h+@nada.kth.se, Mac Hacker Deluxe --
-
- Cookie Jar: Vanilla Yoghurt with Crushed Oreos.
-
- ---------------------------
-
- From: at15+@andrew.cmu.edu (Andrew Lewis Tepper)
- Subject: Proper way to do Self-Modifying code?
- Date: 3 Jan 93 10:55:11 GMT
- Organization: School of Computer Science, Carnegie Mellon, Pittsburgh, PA
-
- I'm writing a BitBlt routine that must be _very_ fast. I want to do
- animation of many large 256 color objects of a game. It seems the
- quickest way to do this would be to take an object before the animation
- starts, and create a sequence of move instructions that would write to
- just those addresses I want. To draw the object I would just load a
- register with the apropriate starting address and call it's draw routine.
-
- Is there an accepted way to do this on the Mac? I know that
- self-modifying code can cause problems on chips with caches, so I want
- to be as "kosher" as possible.
-
- Thanks,
- Andy
-
- +++++++++++++++++++++++++++
-
- Date: 4 Jan 93 12:03:53 GMT
- Organization: Royal Institute of Technology, Stockholm, Sweden
-
- In <wfFp_jO00WB707kGgq@andrew.cmu.edu> at15+@andrew.cmu.edu (Andrew Lewis Tepper) writes:
-
- >Is there an accepted way to do this on the Mac? I know that
- >self-modifying code can cause problems on chips with caches, so I want
- >to be as "kosher" as possible.
-
- if ( TrapAvailable ( _HwPriv ) ) {
-
- /* FIC also calls FlushDataCache */
- FlushInstructionCache ( ) ;
- }
-
- Of course you'll want to put the result of TrapAvailable in
- a global at startup. Not to mention first modifying ALL the
- figures, then flushing the cache ONCE before starting to
- call the code.
-
- However, I think you could write the code quite conflict-free
- and as fast using just address-register-relative addressing
- and maybe a data register for rowBytes. Modifying the instructions
- data takes time to do; I think using a register pair would be
- FASTER - and more compatible.
-
- Cheers,
-
- / h+
-
- - --
- -- Jon W{tte, h+@nada.kth.se, Mac Hacker Deluxe --
-
- -- I don't fear death, it's dying that scares me.
-
- +++++++++++++++++++++++++++
-
- From: alexr@apple.com (Alexander M. Rosenberg)
- Date: 5 Jan 93 18:33:37 GMT
- Organization: Hackers Anonymous
-
- In article <1993Jan4.120353.16699@kth.se> Jon Wltte, d88-jwa@dront.nada.kth.se
- writes:
- > However, I think you could write the code quite conflict-free
- > and as fast using just address-register-relative addressing
- > and maybe a data register for rowBytes. Modifying the instructions
- > data takes time to do; I think using a register pair would be
- > FASTER - and more compatible.
-
- Immediate moved bitmaps are _much_ faster than those drawn via table lookups.
- This is a technique that they call "Compiled Bitmaps" in rec.games.programmer.
- Immediate move instructions are generally faster than using an address
- register. It adds up, especially when lots of small bitmaps may be necessary.
-
- The one shot compile may even be possible to do at compile time, depending on
- the way the screen bitmap is available on the target machine. The problem with
- compiled bitmaps is that they typically are double in size over the plan data,
- which is why Andy would want to compile them when the game is launched.
- Several games take a long time to start up, like Maelstrom (although this is
- probably because Maelstrom keeps all it's sprite data as icl8 resources, and
- loading, locking, and detaching that many resources takes time).
- - ---------------------------------------------------------------------------
- - - Alexander M. Rosenberg - INTERNET: alexr@apple.com - Yoyodyne -
- - - 330 Waverley St., Apt B - UUCP:ucbvax!apple!alexr - Propulsion -
- - - Palo Alto, CA 94301 - - Systems -
- - - (415) 329-8463 - Nobody is my employer so - :-) -
- - - (408) 974-3110 - nobody cares what I say. - -
-
- +++++++++++++++++++++++++++
-
- Date: 5 Jan 93 20:25:43 GMT
- Organization: Royal Institute of Technology, Stockholm, Sweden
-
- In <1993Jan5.183337.20064@gallant.apple.com> alexr@apple.com (Alexander M. Rosenberg) writes:
-
- >Immediate move instructions are generally faster than using an address
- >register. It adds up, especially when lots of small bitmaps may be necessary.
-
- Hmm, well, I'm not convinced. Let's say you move a bitmap. Using an
- address register, you will only have to change the register. For a
- "compiled" bitmap, you would have to change each and every immediate
- move instruction. Not to mention that immediate instructions and
- longer, and thus takes more bus cycles in fetch; those bus cycles
- do also compete with the cycles spent writing to VRAM. (Some slow
- NuBus cards take 7 cycles for a longword write, but then fetching
- an 8-byte instruction instead of a 4-byte one takes 4 extra cycles
- on an LC)
-
- It all comes out in amortized performance; if the blitting has to be
- raving fast, but you have ample of time to precompute the next
- image, compiled bitmaps would be OK (except they flush the cache on
- 040s; that's bad speed-wise) but if you have general throughput
- problems, register-relative blitting is DEFINATELY the right thing
- to do.
-
- Just pass rowBytes in d0 and the address of the first pixel in
- a0, and make VERY SURE that address is longword aligned or you
- will suffer much more from misaligned writes than you will from
- the difference in register-based and immediate addressing.
-
- >The one shot compile may even be possible to do at compile time, depending on
- >the way the screen bitmap is available on the target machine. The problem with
-
- Not on the Mac, of course. However, certain other systems have
- a measly register set and the screen card (note the singularis)
- on a fixed address; I'm sure the timings you cite are for VGA
- and not for anything flexible like the mac QD device model.
-
- Cheers,
-
- / h+
-
- - --
- -- Jon W{tte, h+@nada.kth.se, Mac Hacker Deluxe --
- This signature is kept shorter than 4 lines in the interests of UseNet
- S/N ratio.
-
- +++++++++++++++++++++++++++
-
- From: kent@lloyd.Camex.COM (Kent Borg)
- Date: 5 Jan 93 21:31:38 GMT
- Organization: Camex Inc., Boston MA
-
- In article <1993Jan4.120353.16699@kth.se> d88-jwa@dront.nada.kth.se (Jon Wdtte) writes:
- >In <wfFp_jO00WB707kGgq@andrew.cmu.edu> at15+@andrew.cmu.edu (Andrew Lewis Tepper) writes:
- >
- >>Is there an accepted way to do this on the Mac? I know that
- >>self-modifying code can cause problems on chips with caches, so I want
- >>to be as "kosher" as possible.
-
- I hate being non-Kosher, but just today some of my code was modifying
- itself. (How can a proc in the sleep queue find my A5 world anyway?)
-
- My "to do" list said I should check before I trap, so I added:
-
- > if ( TrapAvailable ( _HwPriv ) ) {
- >
- > /* FIC also calls FlushDataCache */
- > FlushInstructionCache ( ) ;
- > }
-
- It didn't work.
-
- At least with my .h-files, the spelling is "HWTrap". (And now I need
- to type in the source for TrapAvailable()--now I remember why I didn't
- do this before.)
-
- Yes, trivial, so instead consider my post as follows: How should one
- find one's A5 world from within a sleep queue procedure?
-
-
- - --
- Kent Borg kent@camex.com or kentborg@aol.com (when it is *working*)
- H:(617) 776-6899 W:(617) 426-3577
- As always, things look better when some costs are left out.
- -Economist 3-28-92 p. 94
-
- +++++++++++++++++++++++++++
-
- From: neeri@iis.ethz.ch (Matthias Neeracher)
- Date: 7 Jan 93 22:23:29 GMT
- Organization: Integrated Systems Laboratory, ETH, Zurich
-
- In article <1993Jan05.163138.20910@lloyd.Camex.COM>, kent@lloyd.Camex.COM (Kent Borg) writes:
- > Yes, trivial, so instead consider my post as follows: How should one
- > find one's A5 world from within a sleep queue procedure?
-
- I have never written a sleep queue proc, but wouldn't the following work ?
-
- TYPE TheBigSleep =
- RECORD
- sleepy : SleepQRec;
- wonderfulWorld: A5WorldPtr; /* Whatever you want */
- END;
- ...
- valium : TheBigSleep;
- ...
- SleepQInstall(@valium);
-
- According to TFM, your sleep routine will be called with a pointer to
- valium in A0 that it can cast to the appropriate type. Am I missing anything ?
-
- Matthias
-
- - -----
- Matthias Neeracher neeri@iis.ethz.ch
- "I wouldn't recommend sex, drugs or insanity for everyone, but
- they've always worked for me." -- Hunter S. Thompson
-
- +++++++++++++++++++++++++++
-
- From: kent@lloyd.Camex.COM (Kent Borg)
- Date: 8 Jan 93 17:50:14 GMT
- Organization: Camex Inc., Boston MA
-
- In article <NEERI.93Jan7232329@iis.ethz.ch> neeri@iis.ethz.ch (Matthias Neeracher) writes:
- >In article <1993Jan05.163138.20910@lloyd.Camex.COM>, kent@lloyd.Camex.COM (Kent Borg) writes:
- >> Yes, trivial, so instead consider my post as follows: How should one
- >> find one's A5 world from within a sleep queue procedure?
- >
- >I have never written a sleep queue proc, but wouldn't the following work ?
- >
- >TYPE TheBigSleep =
- > RECORD
- > sleepy : SleepQRec;
- > wonderfulWorld: A5WorldPtr; /* Whatever you want */
- > END;
- >...
- >valium : TheBigSleep;
- >...
- >SleepQInstall(@valium);
- >
- >According to TFM, your sleep routine will be called with a pointer to
- >valium in A0 that it can cast to the appropriate type. Am I missing anything ?
-
- No, you are not missing anything, I was the one missing. Sure looks
- like that will work.
-
- Um, though a healthy dose of "RTFM" is appropiate here, I think there
- is also a little of another effect: "It is always in the *first* place
- you look, you just weren't looking carefully enough when you looked
- there because you didn't yet know how lost it was."
-
- I spotted the A0 note, realized that it was not a pointer to my A5,
- nor was it a refcon, so I looked further. By the time I realized that
- there was no A5 or refcon sitting waiting for me I had forgotten that
- I might use A0 to *find* one. Stupid I am sometimes.
-
- Thanks for the help.
-
- - --
- Kent Borg kent@camex.com or kentborg@aol.com (when it is *working*)
- H:(617) 776-6899 W:(617) 426-3577
- As always, things look better when some costs are left out.
- -Economist 3-28-92 p. 94
-
- ---------------------------
-
- From: tmorrow@oracle.com (Thomas Morrow)
- Subject: help- sound playing w/ bufferCmd
- Date: 2 Jan 93 23:19:12 GMT
- Organization: Oracle Corporation, Belmont, CA
-
-
- I am having trouble using SndDoCommand to play a sampled sound header.
-
- I do:
- SndCommand mySndCmd;
-
- /* mySndH is a handle to a sound header and data */
- /* mySndChan is already properly opened */
- mySndCmd.cmd;
- mySndCmd.param1 = 0;
- mySndCmd.param2 = (long)(*mySndH) & 0xffffff;
- SndDoCommand(mySndChan, mySndCmd, false);
-
- This does not work for some reason; I can't figure out why because if
- I replace the SndDoCommand with a Snd Play, it works:
-
- SndPlay(mySndChan, mySndH, true);
-
- So the channel and header must be alright. I am new to Mac
- programming, and wasn't sure exactly how to set param2 (a long) to the
- header address (Ptr)... The IM IV uses ORD4() to do the type
- conversion, but I am using Think C rather than Lisa Pascal. My way
- seems to work, but what is the elegant way?
-
- Anyway, I use SndChannelStatus to get the status every event loop
- cycle, and the SCStatus returned is blank (zero) in all except CPUload
- (24), ChannelAttributes (initMono), and ChannelBusy (true). How can
- the channel be busy if StartTime == endTime == 0?
-
-
- Please email responses. I will summarize.
-
- Tom tmorrow@us.oracle.com
-
- - --
-
- - ---------------------------------------------------------------------------
- Tom Morrow 3OP4 voice:415-506-2202 Office: 427
- tmorrow@us.oracle.com fax:415-506-7292 Application Object Library
- - ---------------------------------------------------------------------------
-
- +++++++++++++++++++++++++++
-
- From: REEKES@applelink.apple.com (Jim Reekes)
- Date: Wed, 6 Jan 1993 00:36:46 GMT
- Organization: Apple Computer, Inc.
-
- In article <TMORROW.93Jan2151912@af4hp.oracle.com>, tmorrow@oracle.com
- (Thomas Morrow) wrote:
- >
- >
- > I am having trouble using SndDoCommand to play a sampled sound header.
- >
- > I do:
- > SndCommand mySndCmd;
- >
- > /* mySndH is a handle to a sound header and data */
- > /* mySndChan is already properly opened */
- > mySndCmd.cmd;
- > mySndCmd.param1 = 0;
- > mySndCmd.param2 = (long)(*mySndH) & 0xffffff;
- > SndDoCommand(mySndChan, mySndCmd, false);
- >
- > This does not work for some reason; I can't figure out why because if
- > I replace the SndDoCommand with a Snd Play, it works:
- >
- > SndPlay(mySndChan, mySndH, true);
- >
- > So the channel and header must be alright. I am new to Mac
- > programming, and wasn't sure exactly how to set param2 (a long) to the
- > header address (Ptr)... The IM IV uses ORD4() to do the type
- > conversion, but I am using Think C rather than Lisa Pascal. My way
- > seems to work, but what is the elegant way?
- >
- > Anyway, I use SndChannelStatus to get the status every event loop
- > cycle, and the SCStatus returned is blank (zero) in all except CPUload
- > (24), ChannelAttributes (initMono), and ChannelBusy (true). How can
- > the channel be busy if StartTime == endTime == 0?
-
- You cannot use the 'snd ' resource for the bufferCmd. You must point to the
- SoundHeader within the resource. Also, the code above didn't set the cmd
- to bufferCmd. Here's some code anyone can use to find the sound header in a
- 'snd ' resource. Then change your code above into...
-
- mySndCmd.cmd = bufferCmd;
- mySndCmd.param1 = 0;
- mySndCmd.param2 = (long) *mySndH + offset;
- err = SndDoCommand(mySndChan, &mySndCmd, true);
-
-
- // find the sound header inside of the given snd handle
-
- OSErr GetBufferOffset(Handle sndHandle, long *offset)
- {
- short howManyCmds;
- Ptr cruisePtr;
- OSErr result;
-
- if (sndHandle == nil)
- return nilHandleErr;
-
- if (*sndHandle == nil)
- return nilHandleErr;
-
- result = noErr;
- *offset = 0;
-
- // set the pointer past the first two words of the snd
- // this is correct for both format 1 and 2 resources
- cruisePtr = *sndHandle + offsetof(SndListResource, modifierPart);
-
- // if it's a format 1, then point past the modifier parts
- if ( ((SndListPtr)*sndHandle)->format == firstSoundFormat )
- cruisePtr += sizeof(ModRef) *
- ((SndListPtr)*sndHandle)->numModifiers;
-
- // now pointing at number of cmds
- howManyCmds = *((short *)cruisePtr);
- cruisePtr += sizeof(howManyCmds);
-
- // cruisePtr is now at the first sound command
- // cruise all commands and find a soundCmd or bufferCmd
- do {
- switch (((SndCmdPtr)cruisePtr)->cmd) {
-
- case (soundCmd | dataOffsetFlag):
- case (bufferCmd | dataOffsetFlag):
- *offset = ((SndCmdPtr)cruisePtr)->param2;
- howManyCmds = 0; // done, get out of loop
- break;
-
- default: // catch any other type of
- cmd
- cruisePtr += sizeof(SndCommand);
- howManyCmds -= 1;
- break;
- }
- } while (howManyCmds >= 1); // done with all the
- commands
-
- if (*offset == 0) // never found sound header
- return badFormat;
-
- return(result);
- }
-
-
-
- - -----------------------------------------------------------------------
- Jim Reekes, Polterzeitgeist | Macintosh Toolbox Engineering
- | Sound Manager Expert
- Apple Computer, Inc. | "All opinions expressed are mine, and do
- 20525 Mariani Ave. MS: 81-KS | not necessarily represent those of my
- Cupertino, CA 95014 | employer, Apple Computer Inc."
-
- ---------------------------
-
- From: Sproul@sproul.sproul.com (Mark Sproul)
- Subject: code for Finding Prefs File (long)
- Date: 5 Jan 93 18:15:16 GMT
- Organization: Sproul Consulting
-
- Below is code for finding and working with prefs file in system 7
- prefernce folder and working with said file
-
- There are people looking for this code again, I posted it before.
- Since I posted it last, I have made some additions to it. This code
- is originally from Inside Mac Comm ToolBox.
-
- ============================================================================
- FILE: doPrefs.proto.h
- ============================================================================
-
- void getPrefsFile(Str255, OSType, OSType);
- Boolean getPrefsResourceStr(Str255, OSType, Str255);
- Boolean getPrefsResourceData(Str255, OSType, char *, long);
- void setPrefsResourceStr(Str255, OSType, Ptr, long);
- void setCTBpref(Str255);
- void DoCommPortSetup(Str255);
-
- ============================================================================
- FILE: doPrefs.c
- ============================================================================
-
-
- /******************************************************************************
- * adapted from
- * Inside the Macintosh Communications Toolbox
- * Page 333
- * After initialization, the code shown first checks if a
- * preferences folder, which contains tool settings written in preference
- * files, already exists. If so, the application uses the settings in this file.
- * Otherwise, the code generates a new preferences file.
- ******************************************************************************
- * Modifications
- ******************************************************************************
- * Nov 27, 1991 Original version had a bug in it.
- * If the "Preferences" directory already existed, the preferences file
- * was placed in the system folder, not in the "Preferences" directory.
- * If the directory did NOT exist, everything worked fine.
- * I also changed it to check for the existance of the "Preferences" folder
- * first instead of trying to create one and letting an duplicate file error
- * indicate that it already existed.
- * by Mark Sproul
- * AppleLink: Sproul.M
- * Jan 16, 1992 Working on a general purpose prefs file manipulator
- * Jan 25, 1992 Prefs file resources working great
- ******************************************************************************/
-
- #include <Connections.h>
- #include <CommResources.h>
- #include "doPrefs.proto.h"
- /*
- ** Global Variables used by all of the prefs routines
- */
- long prefDirID; /* Prefs Dir ID number */
- long sysfDirID; /* System folder Dir ID number */
- short prefVRefNum; /* Prefs Volume Ref number */
- short prefFileOKFlag = 0; /* prefs file OK indicator */
-
- /*************************************************************
- * This makes sure there is a prefs file in the PREFERENCES directory
- * if not, it creates it.
- *
- * getPrefsFile MUST be called before any atempt at getting the prefs values
- *
- *************************************************************/
-
- void getPrefsFile(prefsFileName, creatorType, fileType)
- Str255 prefsFileName;
- OSType creatorType;
- OSType fileType;
- {
- OSErr osErr = noErr;
- SysEnvRec theWorld;
- CInfoPBPtr infoPB;
- WDPBPtr wdPB;
- HParmBlkPtr dirPB;
-
- short prefRefNum;
- Point where = { 75, 75 };
- Str63 toolName;
- short procID;
- Handle h;
- Ptr p;
-
-
- ConnHandle prefConn;
-
- ConnHandle docConn;
- CMBufferSizes sizes = { 0, 0, 0, 0, 0, 0, 0, 0 };
-
-
-
- infoPB = (CInfoPBPtr)NewPtrClear(sizeof(*infoPB));
- wdPB = (WDPBPtr)NewPtrClear(sizeof(*wdPB));
- dirPB = (HParmBlkPtr)NewPtrClear(sizeof(*dirPB));
-
-
- /* find the system folder's volume reference number and directory ID */
- osErr = SysEnvirons(curSysEnvVers, &theWorld);
- (*wdPB).ioVRefNum = theWorld.sysVRefNum;
-
- if (noErr == (osErr = PBGetWDInfo(wdPB, false)))
- {
- /*********************************************************
- * 11-27-91 Modified by Mark Sproul
- **********************************************************/
- /* get the Volume Reference Number and save it */
- prefVRefNum = (*wdPB).ioWDVRefNum;
- /* get the System directory ID and save it */
- sysfDirID = (*wdPB).ioWDDirID;
-
- /* check for the preferences folder */
- (*infoPB).hFileInfo.ioFDirIndex = 0;
- (*infoPB).hFileInfo.ioVRefNum = prefVRefNum;
- (*infoPB).hFileInfo.ioDirID = sysfDirID;
- (*infoPB).hFileInfo.ioNamePtr = "\pPreferences";
- osErr = PBGetCatInfo(infoPB, false);
- /* save the "Preferecnces" dir number */
- prefDirID = (*infoPB).hFileInfo.ioDirID;
-
- if (osErr == fnfErr)
- {
- /* Create "Preferences" folder */
- (*dirPB).fileParam.ioVRefNum = prefVRefNum;
- (*dirPB).fileParam.ioDirID = sysfDirID;
- (*dirPB).fileParam.ioNamePtr = "\pPreferences";
- osErr = PBDirCreate(dirPB, false);
- prefDirID = (*dirPB).fileParam.ioDirID;
- }
-
- /*********************************************************
- * end of modifications
- **********************************************************/
- if (osErr == noErr)
- {
- /* does the preference file exist? */
- (*infoPB).hFileInfo.ioFDirIndex = 0;
- (*infoPB).hFileInfo.ioVRefNum = prefVRefNum;
- (*infoPB).hFileInfo.ioDirID = prefDirID;
- (*infoPB).hFileInfo.ioNamePtr = prefsFileName;
- osErr = PBGetCatInfo(infoPB, false);
- if (osErr == noErr)
- {
- /* set flag saying the prefs file is OK */
- prefFileOKFlag = 0xAA;
- }
- if (osErr == fnfErr)
- {
- /* no, so create a new preference file */
- if (noErr == (osErr = HCreate(prefVRefNum, prefDirID, prefsFileName, creatorType, fileType)))
- {
- HCreateResFile(prefVRefNum, prefDirID, prefsFileName);
- if (noErr == (osErr = ResError()))
- {
- /* open the preference file */
- prefRefNum = HOpenResFile(prefVRefNum, prefDirID, prefsFileName, fsRdWrPerm);
- if (prefRefNum == -1)
- {
- osErr = ResError();
- }
- else
- {
- /* create a default connection */
- osErr = CRMGetIndToolName(classCM, 1,toolName);
- if (noErr == osErr)
- {
- prefConn = CMNew(CMGetProcID(toolName), cmData, sizes, 0, 0);
- /* leave the default setting as the preferance */
-
- /************************************************************
- * ORIGINALLY, the code let the user select setup at this point
- * I do not want it asking for serial port prefs on startup
- * if they are not set.
- * ---allow the user to select a prefered tool and configuration
- * ---osErr = CMChoose(&prefConn, where, nil);
- ************************************************************/
-
- /* write the prefered tool name to the preference file */
- HLock((Handle) prefConn);
- CMGetToolName((**prefConn).procID, toolName);
- HUnlock((Handle) prefConn);
- h = NewHandle(1 + toolName[0]);
- HLock(h);
- BlockMove(toolName, *h, GetHandleSize(h));
- HUnlock(h);
- AddResource(h, 'pTXT', 0, "");
- ReleaseResource(h);
- /* write the prefered configuration to the preference file */
- p = CMGetConfig(prefConn);
- h = NewHandle(GetPtrSize(p));
- HLock(h);
- BlockMove(p, *h, GetHandleSize(h));
- HUnlock(h);
- AddResource(h, 'cTXT', 0, "");
- ReleaseResource(h);
- DisposPtr(p);
-
- /* dispose of the connection */
- CMDispose(prefConn);
- }
- /* close the file so that it can be used in a shared environment */
- CloseResFile(prefRefNum);
- /* set flag saying the prefs file is OK */
- prefFileOKFlag = 0xAA;
- }
- }
- }
- }
- }
- }
- }
-
-
-
- //**************************************
- //* get resource String from Prefs file
- //*
- //***************************************
- Boolean getPrefsResourceStr(prefsFileName, perfsResType, returnString)
- Str255 prefsFileName;
- OSType perfsResType;
- Str255 returnString;
- {
- short prefRefNum;
- Handle h;
- int i;
- Size hSize;
- Boolean returnFlag;
-
- h = nil;
- returnFlag = false;
- /* did the prefs file get opened or created OK */
- if (prefFileOKFlag == 0xAA)
- {
- /* focus on the preference file */
- prefRefNum = HOpenResFile(prefVRefNum, prefDirID, prefsFileName, fsRdWrPerm);
- if (prefRefNum != -1)
- {
- h = Get1Resource(perfsResType, 0);
- if (h != nil)
- {
- hSize = GetHandleSize(h); /* get the size of the handle */
- if (hSize > 255) hSize = 255;
- HLock(h);
- /* had to have this to make it compile under THINK C 5.0 */
- for (i=0; i< hSize; i++)
- {
- returnString[i] = *(*h+i);
- }
- HUnlock(h);
- ReleaseResource(h);
- returnFlag = true; //* prefs string is OK
- }
- CloseResFile(prefRefNum);
- }
- }
- else
- {
- //* generate prefs file alert message
- }
- return(returnFlag);
- }
-
- //**************************************
- //* get resource String from Prefs file
- //*
- //***************************************
- Boolean getPrefsResourceData( Str255 prefsFileName,
- OSType perfsResType,
- char *returnString,
- long maxLen)
- {
- short prefRefNum;
- Handle h;
- int i;
- Size hSize;
- Boolean returnFlag;
-
- h = nil;
- returnFlag = false;
- /* did the prefs file get opened or created OK */
- if (prefFileOKFlag == 0xAA)
- {
- /* focus on the preference file */
- prefRefNum = HOpenResFile(prefVRefNum, prefDirID, prefsFileName, fsRdWrPerm);
- if (prefRefNum != -1)
- {
- h = Get1Resource(perfsResType, 0);
- if (h != nil)
- {
- hSize = GetHandleSize(h); /* get the size of the handle */
- if (hSize > maxLen) hSize = maxLen;
- HLock(h);
- /* had to have this to make it compile under THINK C 5.0 */
- for (i=0; i< hSize; i++)
- {
- returnString[i] = *(*h+i);
- }
- HUnlock(h);
- ReleaseResource(h);
- returnFlag = true; //* prefs string is OK
- }
- CloseResFile(prefRefNum);
- }
- }
- else
- {
- //* generate prefs file alert message
- }
- return(returnFlag);
- }
-
- //**************************************
- //* save resource to Prefs file
- //*
- //***************************************
- void setPrefsResourceStr(Str255 prefsFileName, OSType perfsResType,char *buffer, long bufLen)
- {
- short prefRefNum;
- Handle h;
- int i;
- Size hSize, newSize;
-
- h = nil;
- /* did the prefs file get opened or created OK */
- if (prefFileOKFlag == 0xAA)
- {
- /* focus on the preference file */
- prefRefNum = HOpenResFile(prefVRefNum, prefDirID, prefsFileName, fsRdWrPerm);
- if (prefRefNum != -1)
- {
- //* get the specified resource */
- h = Get1Resource(perfsResType, 0);
- if (h == nil)
- {
- /* resource did not exist, add it to resource file */
- h = NewHandle(1 + bufLen);
- HLock(h);
- BlockMove(buffer, *h, GetHandleSize(h));
- HUnlock(h);
- AddResource(h, perfsResType, 0, "\p");
- }
- else
- {
- /* resoure DOES exist, change it */
- hSize = GetHandleSize(h); /* get the size of the handle */
- /* check for size of handle */
- if (hSize != (1 + bufLen))
- {
- newSize = 1 + bufLen;
- SetHandleSize(h, newSize);
- }
- HLock(h);
- BlockMove(buffer, *h, GetHandleSize(h));
- HUnlock(h);
- ChangedResource(h);
- }
- ReleaseResource(h);
- CloseResFile(prefRefNum);
- }
- }
- else
- {
- PutAlertMessage("\pProgram cant find prefs file");
- }
- }
-
-
- /**************************************
- * set Comm Tool Box connection preference
- *
- ****************************************/
- void setCTBpref(prefsFileName)
- Str255 prefsFileName;
- {
- short prefRefNum;
- OSErr osErr, cmChooseReturnCode;
- int i;
- Str255 prefStr;
- short procID;
- Str63 toolName;
- Handle h;
- Ptr p;
- short iErr;
- Size hSize, newSize;
-
- ConnHandle docConn;
- CMBufferSizes sizes = { 0, 0, 0, 0, 0, 0, 0, 0 };
- Point where = { 40, 40 };
-
- if (isCTBavailable())
- {
- /* did the prefs file get opened or created OK */
- if (prefFileOKFlag == 0xAA)
- {
- getPrefsResourceStr(prefsFileName,'pTXT', prefStr);
-
- procID = CMGetProcID(prefStr);
- if (procID != -1)
- {
- /* create a new connection */
- docConn = CMNew(procID, cmData, sizes, 0, 0);
-
- if (docConn != nil)
- {
- /* set the prefered configuration */
-
- getPrefsResourceStr(prefsFileName,'cTXT', prefStr);
- osErr = CMSetConfig(docConn, (char *)prefStr);
-
- cmChooseReturnCode = CMChoose(&docConn, where, nil);
- }
- }
- else
- {
- /* the prefered tool could not be found so I */
- osErr = CRMGetIndToolName(classCM, 1, toolName);
- docConn = CMNew(CMGetProcID(toolName), cmData, sizes, 0, 0);
- if (docConn != nil)
- {
- cmChooseReturnCode = CMChoose(&docConn, where, nil);
- }
- }
-
- if ((cmChooseReturnCode == chooseOKMinor) || (cmChooseReturnCode == chooseOKMajor))
- {
- /* change the prefs file */
-
- if (prefFileOKFlag == 0xAA)
- {
- /* open the preference file */
- prefRefNum = HOpenResFile(prefVRefNum, prefDirID, prefsFileName, fsRdWrPerm);
- if (prefRefNum != -1)
- {
- /* write the prefered tool name to the preference file */
- HLock((Handle) docConn);
- CMGetToolName((**docConn).procID, toolName);
- HUnlock((Handle) docConn);
-
- /* get the port TeXT resource */
- h = Get1Resource('pTXT', 0);
- if (h == nil)
- {
- /* resource did not exist, add it to resource file */
- h = NewHandle(1 + toolName[0]);
- HLock(h);
- BlockMove(toolName, *h, GetHandleSize(h));
- HUnlock(h);
- AddResource(h, 'pTXT', 0, "");
- }
- else
- {
- /* resoure DOES exist, change it */
- hSize = GetHandleSize(h); /* get the size of the handle */
- /* check for size of handle */
- if (hSize != (1 + toolName[0]))
- {
- newSize = 1 + toolName[0];
- SetHandleSize(h, newSize);
- }
- HLock(h);
- BlockMove(toolName, *h, GetHandleSize(h));
- HUnlock(h);
- ChangedResource(h);
- }
- ReleaseResource(h);
-
- /* write the prefered configuration to the preference file */
- p = CMGetConfig(docConn);
-
-
- /* get the configuration TeXT resource */
- h = Get1Resource('cTXT', 0);
- if (h == nil)
- {
- /* resource did not exist, add it to resource file */
- h = NewHandle(GetPtrSize(p));
- HLock(h);
- BlockMove(p, *h, GetHandleSize(h));
- HUnlock(h);
-
- AddResource(h, 'cTXT', 0, "");
- iErr = ResError();
- }
- else
- {
- /* resoure DOES exist, change it */
- hSize = GetHandleSize(h); /* get the size of the handle */
- /* check for size of handle */
- if (hSize != GetPtrSize(p))
- {
- newSize = GetPtrSize(p);
- SetHandleSize(h, newSize);
- }
- HLock(h);
- BlockMove(p, *h, GetHandleSize(h));
- HUnlock(h);
- ChangedResource(h);
- }
- ReleaseResource(h);
-
- CloseResFile(prefRefNum);
- iErr = ResError();
- DisposPtr(p);
- }
- }
- }
-
- if (docConn != nil)
- {
- /* dispose of the connection */
- CMDispose(docConn);
- }
-
- }
- }
- else
- {
- SysBeep(1);
- SysBeep(1);
- }
- }
-
-
- void DoCommPortSetup(prefsFileName)
- Str255 prefsFileName;
- {
- setCTBpref(prefsFileName);
-
- }
-
- - -----------------------------------------------------
- Mark Sproul - KB2ICI - New Jersey
- sproul@sproul.com
-
- +++++++++++++++++++++++++++
-
- From: grobbins@Apple.COM (Grobbins)
- Date: 7 Jan 93 09:42:05 GMT
- Organization: Mac Experimental System Software
-
- In article <D2150096.mv05jr@sproul.sproul.com> Sproul@sproul.sproul.com (Mark Sproul) writes:
- >Below is code for finding and working with prefs file in system 7
- >prefernce folder and working with said file
-
- Modern Mac applications should use the FindFolder call to locate
- the Preferences folder. For an example, see the DTS snippet prefs
- (available via anonymous ftp from ftp.apple.com, in the directory
- /dts/mac/sc/snippets/toolbox.) FindFolder is documented in the
- Finder Interface chapter of Inside Mac VI.
-
- Grobbins grobbins@apple.com
-
- No disclaimers apply.
-
- +++++++++++++++++++++++++++
-
- From: neeri@iis.ethz.ch (Matthias Neeracher)
- Date: 7 Jan 93 22:41:43 GMT
- Organization: Integrated Systems Laboratory, ETH, Zurich
-
- In article <D2150096.mv05jr@sproul.sproul.com>, Sproul@sproul.sproul.com (Mark Sproul) writes:
-
- > Below is code for finding and working with prefs file in system 7
- > prefernce folder and working with said file
-
- Why is this code better than FindFolder() ?
-
- > /* check for the preferences folder */
- > (*infoPB).hFileInfo.ioFDirIndex = 0;
- > (*infoPB).hFileInfo.ioVRefNum = prefVRefNum;
- > (*infoPB).hFileInfo.ioDirID = sysfDirID;
- > (*infoPB).hFileInfo.ioNamePtr = "\pPreferences";
-
- >From SysTypes.r:
-
- #define Language langEnglish, langFrench, langGerman, langItalian,
- langDutch, langSwedish, langSpanish, langDanish, \
- langPortuguese, langNorwegian, langHebrew, \
- langJapanese, langArabic, langFinnish, langGreek, \
- langIcelandic, langMaltese, langTurkish, \
- langCroatian, langTradChinese, langUrdu, \
- langHindi, langThai, langKorean, langLithuanian, \
- langPolish, langHungarian, langEstonian, \
- langLettish, langLappish, langFaeroese, \
- langFarsi, langRussian, langSimpChinese, \
- langFlemish, langIrish, langAlbanian, langRomanian, \
- langCzech, langSlovak, langSlovenian, langYiddish, \
- langSerbian, langMacedonian, langBulgarian, \
- langUkrainian, langByelorussian, langUzbek, \
- langKazakh, langAzerbaijani, langAzerbaijanAr, \
- langArmenian, langGeorgian, langMoldavian, \
- langKirghiz, langTajiki, langTurkmen, \
- langMongolian, langMongolianCyr, langPashto, \
- langKurdish, langKashmiri, langSindhi, langTibetan, \
- langNepali, langSanskrit, langMarathi, langBengali, \
- langAssamese, langGujarati, langPunjabi, langOriya, \
- langMalayalam, langKannada, langTamil, langTelugu, \
- langSinhalese, langBurmese, langKhmer, langLao, \
- langVietnamese, langIndonesian, langTagalog, \
- langMalayRoman, langMalayArabic, langAmharic, \
- langTigrinya, langGalla, langSomali, langSwahili, \
- langRuanda, langRundi, langChewa, langMalagasy, \
- langEsperanto, langUnspecified = 32767 \
-
- Are you sure that the speakers of all of these languages will be happy
- with your hardcoding the name "Preferences" ?
-
- Matthias
-
- - -----
- Matthias Neeracher neeri@iis.ethz.ch
- "There once was an Age of Reason, but we've progressed beyond it."
- -- Ayn Rand, _Atlas Shrugged_
-
- +++++++++++++++++++++++++++
-
- From: jesjones@stein.u.washington.edu (Jesse Jones)
- Date: 9 Jan 1993 05:28:21 GMT
- Organization: University of Washington, Seattle
-
-
- There has been some discussion lately about how to handle a preferences
- file, so I thought I'd post my code. It's nothing astounding, but I think
- it has some advantages over the previously posted code:
-
- 1) FindFolder and the high level file manager routines are used so
- the code is quit a bit easier to follow.
- 2) The GetPref procedure is passed a procedure parameter that is used to
- return a default preference if the preference is missing from the
- Prefs file.
- 3) Individual preferences are referenced by the ResType, resource name,
- and version number. If the version numbers don't match the default
- preference is returned.
-
-
- --Jesse
-
-
- Here is the interface for the Prefs module. It's written in SemperSoft
- Modula-2. HANDLE is compatible with any pointer to pointer and Mstring is
- a 256-byte string terminated with zero.
-
- DEFINITION MODULE Prefs; (* By Jesse Jones, 1992 *)
-
-
- FROM SYSTEM IMPORT HANDLE;
- FROM Types IMPORT Str255, Mstring;
-
-
- TYPE
- PrefsProc = PROCEDURE(): HANDLE;
-
- VAR
- PrefsName: Str255; (* Name of the Preferences file. *)
-
-
- PROCEDURE GetPref (rType, rName: Mstring; vers: INTEGER; default: PrefsProc): HANDLE;
- (* default is called if Prefs not present or version <> vers. *)
-
- PROCEDURE SetPref (rType, rName: Mstring; vers: INTEGER; data: HANDLE);
- (* Change or add a preference. *)
-
- PROCEDURE PrefPresent (rType, rName: Mstring; vers: INTEGER): BOOLEAN;
-
- PROCEDURE DeletePref (rType, rName: Mstring);
-
-
- END Prefs.
-
- And here is the implementation of the Prefs module.
-
- IMPLEMENTATION MODULE Prefs;
-
- (* Import list deleted *)
-
- (* Version numbers are saved in PVRS resources. These resources contain a
- single integer for the version number and are referenced by name, with
- the name being the concatenation of the preference resource type and
- the preference's name. *)
- PROCEDURE GetVersion (rType, rName: Mstring): INTEGER;
- VAR
- data: IntHandle;
- str : Str255;
- vers: INTEGER;
- err : OSErr;
- BEGIN
- str := StrToPStr(Concat(rType, rName));
- data := Get1NamedResource('PVRS', str);
- err := ResError();
- IF (err = resNotFound) OR (data = NIL) THEN
- vers := -1;
- ELSIF ErrCheck(err) THEN
- vers := data^^;
- ELSE
- vers := -1;
- END;
- RETURN vers;
- END GetVersion;
-
- PROCEDURE SetVersion (rType, rName: Mstring; version: INTEGER);
- VAR
- data : IntHandle;
- str : Mstring;
- err : OSErr;
- dummy: BOOLEAN;
- BEGIN
- str := Concat(rType, rName);
- data := Get1NamedResource('PVRS', StrToPStr(str));
- err := ResError();
- IF (err = resNotFound) OR (data = NIL) THEN
- data := CreateHandle(SIZE(INTEGER));
- data^^ := version;
- dummy := InsertResource('PVRS', str, 0, data, TRUE);
- ELSIF ErrCheck(err) THEN
- data^^ := version;
- dummy := ChangeResource(data);
- END;
- END SetVersion;
-
- PROCEDURE OpenPrefs (VAR refNum: INTEGER; perm: SignedByte): BOOLEAN;
- VAR
- vRef : INTEGER;
- dir : LONGINT;
- err : OSErr;
- dummy: BOOLEAN;
- BEGIN
- err := FindPrefsFolder(vRef, dir); (* find (or create) prefs folder *)
- IF ErrCheck(err) THEN
- refNum := HOpenResFile(vRef, dir, PrefsName, perm); (* open prefs file *)
- err := ResError();
- IF err = fnfErr THEN (* if prefs file is missing *)
- HCreateResFile(vRef, dir, PrefsName); (* then create it *)
- refNum := HOpenResFile(vRef, dir, PrefsName, perm); (* and open the new file *)
- err := ResError();
- dummy := ErrCheck(err);
- END;
- END;
- RETURN err = noErr;
- END OpenPrefs;
-
- PROCEDURE GetPref (rType, rName: Mstring; vers: INTEGER; default: PrefsProc): HANDLE;
- VAR
- refNum: INTEGER;
- data : HANDLE;
- err : OSErr;
- BEGIN
- IF OpenPrefs(refNum, fsRdPerm) THEN
- IF GetVersion(rType, rName) <> vers THEN
- data := default();
- ELSE
- data := Get1NamedResource(StrToOS(rType), StrToPStr(rName));
- err := ResError();
- IF (err = resNotFound) OR (data = NIL) THEN
- data := default();
- ELSIF ErrCheck(err) THEN
- DetachResource(data);
- HNoPurge(data);
- ELSE
- data := default();
- END;
- END;
- CloseResFile(refNum);
- ELSE
- data := default();
- END;
- Assert(data <> NIL);
- RETURN data;
- END GetPref;
-
- PROCEDURE PrefPresent (rType, rName: Mstring; vers: INTEGER): BOOLEAN;
- VAR
- refNum: INTEGER;
- data : HANDLE;
- found : BOOLEAN;
- err : OSErr;
- BEGIN
- found := FALSE;
- IF OpenPrefs(refNum, fsRdPerm) THEN
- IF GetVersion(rType, rName) >= vers THEN
- data := Get1NamedResource(StrToOS(rType), StrToPStr(rName));
- err := ResError();
- IF (err <> resNotFound) AND (data <> NIL) THEN
- found := ErrCheck(err);
- END;
- END;
- CloseResFile(refNum);
- END;
- RETURN found;
- END PrefPresent;
-
- (* SetPref is the only routine to actually add a preference to the
- Prefs file. Note that the preferences are purgable. *)
- PROCEDURE SetPref (rType, rName: Mstring; vers: INTEGER; data: HANDLE);
- VAR
- refNum: INTEGER;
- old : HANDLE;
- err : OSErr;
- done : BOOLEAN;
- BEGIN
- done := FALSE;
- Assert(data <> NIL);
- IF OpenPrefs(refNum, fsRdWrPerm) THEN
- old := Get1NamedResource(StrToOS(rType), StrToPStr(rName));
- err := ResError();
- IF (err = resNotFound) OR (old = NIL) THEN
- done := InsertResource(rType, rName, 0, data, TRUE);
- ELSIF ErrCheck(err) THEN
- RemoveResource(old);
- done := InsertResource(rType, rName, 0, data, TRUE);
- END;
- IF done THEN
- SetVersion(rType, rName, vers);
- DetachResource(data);
- END;
- CloseResFile(refNum);
- END;
- END SetPref;
-
- PROCEDURE DeletePref (rType, rName: Mstring);
- VAR
- refNum: INTEGER;
- old : HANDLE;
- err : OSErr;
- BEGIN
- IF OpenPrefs(refNum, fsRdWrPerm) THEN
- old := Get1NamedResource(StrToOS(rType), StrToPStr(rName));
- err := ResError();
- IF (err = resNotFound) OR (old = NIL) THEN
- (* do nothing *)
- ELSIF ErrCheck(err) THEN
- RemoveResource(old);
- END;
- CloseResFile(refNum);
- END;
- END DeletePref;
-
-
- BEGIN
- PrefsName := "";
- END Prefs.
-
- InsertResource, ChangeResource, and RemoveResource are some handy resource
- manipulation routines I wrote a while back. I'll post them in a seperate
- message.
-
-
- +++++++++++++++++++++++++++
-
- From: jesjones@stein.u.washington.edu (Jesse Jones)
- Date: 10 Jan 93 01:55:19 GMT
- Organization: University of Washington, Seattle
-
-
- Here are some handy routines for dealing with resources. Several of these
- routines are used by the Prefs code I posted recently. A few of these routines
- replace Apple's standard routines with something that behaves a little better.
-
- --Jesse
-
-
- PROCEDURE Unique (theType: ResType): INTEGER;
- INLINE2(0A9C1H);
-
- (* The toolbox trap, UniqueID, returns an unused positive resource ID
- number. However, application resources need to be larger than 127 to
- avoid conflicts with other resources used by the System. The below
- procedure ensures that the ID is in the correct range. *)
- PROCEDURE UniqueID (theType: ResType; system: BOOLEAN): INTEGER;
- VAR
- ID : INTEGER;
- done: BOOLEAN;
- BEGIN
- REPEAT
- ID := Unique(theType); (* always returns positive IDs *)
- IF system THEN
- done := ID < 128;
- ELSE
- done := ID > 127;
- END;
- UNTIL done;
- RETURN ID;
- END UniqueID;
-
- PROCEDURE Unique1 (theType: ResType): INTEGER;
- INLINE2(0A810H);
-
- PROCEDURE Unique1ID (theType: ResType; system: BOOLEAN): INTEGER;
- VAR
- ID : INTEGER;
- done: BOOLEAN;
- BEGIN
- REPEAT
- ID := Unique1(theType); (* always returns positive IDs *)
- IF system THEN
- done := ID < 128;
- ELSE
- done := ID > 127;
- END;
- UNTIL done;
- RETURN ID;
- END Unique1ID;
-
- PROCEDURE GetResourceName (rsrc: HANDLE): Mstring;
- VAR
- rID : INTEGER;
- kind : ResType;
- rName: Str255;
- BEGIN
- GetResInfo(rsrc, rID, kind, rName);
- RETURN PStrToStr(rName);
- END GetResourceName;
-
- PROCEDURE GetResourceID (rsrc: HANDLE): INTEGER;
- VAR
- rID : INTEGER;
- kind : ResType;
- rName: Str255;
- BEGIN
- GetResInfo(rsrc, rID, kind, rName);
- RETURN rID;
- END GetResourceID;
-
- (* resources can be specified using either name, or ID (if name is ""). *)
- PROCEDURE InsertResource (type, name: Mstring; ID: INTEGER; rsrc: HANDLE; purgeable: BOOLEAN): BOOLEAN;
- VAR
- rName : Str255;
- rType : ResType;
- refNum: INTEGER;
- done : BOOLEAN;
- BEGIN
- done := FALSE;
- rType := StrToOS(type);
- IF name[0] = EOS THEN
- rName := "";
- ELSE
- rName := StrToPStr(name);
- ID := Unique1ID(rType, FALSE);
- END;
- AddResource(rsrc, rType, ID, rName);
- IF ErrCheck(ResError()) THEN
- IF purgeable THEN SetResAttrs(rsrc, resPurgeable) END; (* clears resChanged bit! *)
- IF ErrCheck(ResError()) THEN
- ChangedResource(rsrc);
- IF ErrCheck(ResError()) THEN
- refNum := CurResFile();
- UpdateResFile(refNum);
- done := ErrCheck(ResError());
- END;
- END;
- END;
- RETURN done;
- END InsertResource;
-
- PROCEDURE ChangeResource (rsrc: HANDLE): BOOLEAN;
- VAR
- refNum: INTEGER;
- done : BOOLEAN;
- BEGIN
- done := FALSE;
- ChangedResource(rsrc);
- IF ErrCheck(ResError()) THEN
- refNum := CurResFile();
- UpdateResFile(refNum);
- done := ErrCheck(ResError());
- END;
- RETURN done;
- END ChangeResource;
-
- PROCEDURE RemoveResource (rsrc: HANDLE);
- VAR
- refNum: INTEGER;
- done : BOOLEAN;
- BEGIN
- RmveResource(rsrc);
- IF ErrCheck(ResError()) THEN
- refNum := CurResFile();
- UpdateResFile(refNum);
- KillHandle(rsrc);
- done := ErrCheck(ResError());
- END;
- END RemoveResource;
-
- ---------------------------
-
- End of C.S.M.P. Digest
- **********************
-